package com.zhang.simple.chatgpt;

import com.alibaba.fastjson2.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Member;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * description
 *
 * @author zhangFanJun
 * @date 2024-02-28 9:04
 **/
@Slf4j
@Service
public class ChatService {

    /**
     * 读取消息
     * */
    public void read(ChannelHandlerContext ctx, String receivedMessage) {

        // 解析成对象
        ChatMessage chatMessage = null;
        try {
            chatMessage =JSON.parseObject(receivedMessage, ChatMessage.class);
        } catch (Exception e){
            log.error("消息解析出现异常：{},异常信息：",receivedMessage,e);
            return;
        }

        if (Objects.isNull(chatMessage) || ObjectUtils.isEmpty(chatMessage.getCode())) {
            log.error("异常消息：{}",receivedMessage);
            return;
        }

        // 分析消息
        switch (chatMessage.getCode()) {
            case "user":
                // 绑定用户
                Channel channel = ctx.channel();
                ChannelHold.USER_CHANNEL.put(chatMessage.getUser(),channel);
                log.info("绑定用户：{}",chatMessage.getUser());
                break;
            case "single":
                // 单人聊天，直接发送给对象（如果考虑双人聊天变群聊，可以考虑单人聊天也要创建房间号）
                send(chatMessage.getMessage(),chatMessage.getToList());
                log.info("单人聊天，消息：{}", chatMessage);
                break;
            case "new":
                // 新建房间，前端需要锁定只能开一个窗口或者采用http请求
                String id = UUID.randomUUID().toString();
                ChannelHold.ROOM.put(id,chatMessage.getToList());
                // 返回当前连接
                ctx.writeAndFlush(new TextWebSocketFrame("room:"+id));
                log.info("创建房间：{}，消息：{}",id, chatMessage);
                break;
            case "room":
                // 房间聊天
                List<String> toList = ChannelHold.ROOM.get(chatMessage.getRoom());
                send(chatMessage.getMessage(),toList);
                log.info("房间聊天，消息：{}", chatMessage);
                break;
            default:
        }
    }

    /**
     * 如果是集群，需要采用广播模式发送给所有的服务器
     * */
    private void send(String message, List<String> toList) {
        ChannelHold.USER_CHANNEL.forEach((u,c)->{
            if(toList.contains(u)){
                c.writeAndFlush(new TextWebSocketFrame(message));
            }
        });
    }
}
